package com.sfac.springboot.springboot.config.shiro;

import at.pollux.thymeleaf.shiro.dialect.ShiroDialect;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @Description ShiroConfig
 * @Author JiangHu
 * @Date 2022/8/31 10:19
 */
@Configuration
public class ShiroConfig {

	@Autowired
	private MyRealm myRealm;

	@Bean
	public DefaultWebSecurityManager securityManager() {
		DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
		securityManager.setRealm(myRealm);
		return securityManager;
	}

	/**
	 * anon：匿名访问，无需登录 ---- AnonymousFilter
	 * authc：登录后才能访问 ---- FormAuthenticationFilter
	 * user：登录过能访问 ---- UserFilter
	 * logout：登出 ---- LogoutFilter
	 */
	@Bean
	public ShiroFilterFactoryBean shiroFilterFactoryBean() {
		ShiroFilterFactoryBean filterFactory = new ShiroFilterFactoryBean();
		// 注入安全管理器
		filterFactory.setSecurityManager(securityManager());

		// 设置登录页面、登录成功页面
		filterFactory.setLoginUrl("/login");
		filterFactory.setSuccessUrl("/test/thymeleafTest");

		// 设置其余地址的访问策略
		Map<String, String> filterMap = new LinkedHashMap<>();
		// 匿名策略
		// 登录注册
		filterMap.put("/login", "anon");
		filterMap.put("/register", "anon");
		// 静态资源
		filterMap.put("/favicon.ico", "anon");
		filterMap.put("/css/**", "anon");
		filterMap.put("/images/**", "anon");
		filterMap.put("/js/**", "anon");
		filterMap.put("/vendors/**", "anon");
		filterMap.put("/static/**", "anon");
		// 测试模块
		filterMap.put("/test/**", "anon");
		// api
		filterMap.put("/api/**", "anon");

		// 非匿名策略
		filterMap.put("/**", "authc");
		filterFactory.setFilterChainDefinitionMap(filterMap);

		return filterFactory;
	}

	/**
	 * - 注册shiro方言，让 thymeleaf 支持 shiro 标签
	 */
	@Bean
	public ShiroDialect shiroDialect(){
		return new ShiroDialect();
	}

	/**
	 * DefaultAdvisorAutoProxyCreator, Advisor 代理类生成器
	 */
	@Bean
	@DependsOn({"lifecycleBeanPostProcessor"})
	public DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator(){
		DefaultAdvisorAutoProxyCreator advisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		advisorAutoProxyCreator.setProxyTargetClass(true);
		return advisorAutoProxyCreator;
	}

	/**
	 * - 创建 AuthorizationAttributeSourceAdvisor，扫描 Shiro 注解
	 */
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(){
		AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor();
		authorizationAttributeSourceAdvisor.setSecurityManager(securityManager());
		return authorizationAttributeSourceAdvisor;
	}
}
